/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import routefinder.City;
import routefinder.implementation.RouteFinderExcception;
import routefinder.implementation.RouteFinderExtendedImpl;
import routefinder.implementation.RoutesMapCities;

/**
 *
 * @author Lucas
 */
public class Main {
    private static final Logger LOG = Logger.getLogger(Main.class.getName());

    /**
     * @param args 
     * param0: name of the origin city
     * param1: name of the destination city
     * param2: path to a file containing the graph map
     */
    public static void main(String[] args) throws RouteFinderExcception, FileNotFoundException, IOException {
        City origin = null;
        City destination = null;
        if (args.length < 2) {
            throw new RouteFinderExcception("Usage: java -jar jarName.jar originCityName destinationCityName [graphFile]");
        } else {
            origin = new City(args[0]);
            destination = new City(args[1]);
        }
        String graphDataFileName = null;
        if (args.length == 3) {
            graphDataFileName = args[2];
        }

        final RoutesMapCities map = new RoutesMapCities();
        loadFileIntoMemory(graphDataFileName, map);

        RouteFinderExtendedImpl facade = RouteFinderExtendedImpl.getInstance();
        facade.setRoutesMap(map);        

        LOG.info("Executing algorithm...");

        final int shortestLength = facade.getShortestRouteLength(origin, destination);
        final Map<City, Integer> routes = facade.getAllShortestRouteLengths(origin);

        System.out.println("Shortest length between: " + origin + " and " + destination + ": " + shortestLength);

        System.out.println("Shortest path from origin... ");
        for (Map.Entry<City, Integer> entry : routes.entrySet()) {
            City key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println("To: " + key + " = " + value);
        }
        System.out.println("Reachable destinations: " + routes.size());

        System.out.println("This is the end, my only friend, the eeend. :-)");
    }

    private static void loadFileIntoMemory(String graphDataFileName, final RoutesMapCities map) throws IOException  {
        InputStream is = null;
        if(graphDataFileName != null){
            try {
                is = new FileInputStream(graphDataFileName);
            } catch (FileNotFoundException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.WARNING, "couldn't load file. trying the sample graph.", ex);             
            }
        }
        if(is == null){
            is = Thread.currentThread().getContextClassLoader().getResourceAsStream("exampleGraph.data");
        }
        
        try {
            final BufferedReader bf = new BufferedReader(new InputStreamReader(is));
            LOG.info("Loading graph...");
            String s = null;
            while (true) {
                s = bf.readLine();
                if (s == null) {
                    break;
                }
                StringTokenizer st = new StringTokenizer(s, ",");
                map.addDirectRoute(new City(st.nextToken()), new City(st.nextToken()), Integer.parseInt(st.nextToken()));
            }
        } finally {
            is.close();
        }
    }
}
